<template>
	<el-dialog @opened="opened" append-to-body title="选择项目地址并绘制项目区域" v-bind="$attrs" v-on="$listeners" width="1200px">
		<div class="map-warp" v-loading="!map">
			<div @click="mapUnfoucs" class="left-warp">
				<div class="left-warp-top">
					<el-autocomplete
						:fetch-suggestions="querySearchAsync"
						@select="handleSelect"
						placeholder="详细地址搜索"
						popper-class="poi-autocomplete"
						suffix-icon="el-icon-search"
						v-model="address"
					>
						<div class="poi-content" slot-scope="{item}">
							<div class="poi-name">{{item.name}}</div>
							<div class="poi-address">{{item.address}}</div>
						</div>
					</el-autocomplete>
				</div>
				<div class="left-warp-bottom" ref="left-warp-bottom">
					<ul>
						<li
							:class="item.id === active.id&&'active'"
							:key="item.id"
							@click="poiClick(item)"
							class="poi-item"
							v-for="item in poiList"
						>
							<div class="poi-icon">
								<SvgIcon class-name="marker-icon" iconClass="marker" v-if="item.id === active.id"></SvgIcon>
							</div>
							<div class="poi-content">
								<div class="poi-name">{{item.name}}</div>
								<div class="poi-address">{{item.address}}</div>
							</div>
						</li>
					</ul>
				</div>
			</div>
			<div class="right-warp">
				<SvgIcon class-name="marker-icon" iconClass="marker" v-if="type === 'move'"></SvgIcon>
				<div class="map" id="map-container" ref="map"></div>

				<div class="map-tip">
					<el-alert show-icon title="请点击右下角的“添加区域”按钮绘制您的项目区域，单击即可划线，双击确定区域，选中区域双击编辑区域。点击“添加完成”按钮可退出区域操作" type="info"></el-alert>
				</div>

				<ul class="map-control">
					<li @click="createPolygon">
						<i class="el-icon-plus"></i> 添加区域
					</li>
					<li @click="deletePolygon">
						<i class="el-icon-delete"></i> 删除区域
					</li>
					<li @click="finash">
						<i class="el-icon-check"></i> 添加完成
					</li>
				</ul>
			</div>
		</div>
		<span class="dialog-footer" slot="footer">
			<el-button @click="close">取 消</el-button>
			<el-button @click="confirm" type="primary">确 定</el-button>
		</span>
	</el-dialog>
</template>
<script>
import { colorTheme } from '@/styles/var.scss'
import { getRandomStr } from 'zjy-ui/lib/utils/index'
import AMapLoader from '@amap/amap-jsapi-loader'
export default {
	props: {
		/**
		 * 初始化坐标和区域对象, v-model的值
		 * v-model的初始值可以是{}或者{lnglat:[],polygon:[]}
		 * {
				lnglat: [114.12829, 22.557229], //设置默认的坐标点,没有为空或[],为空时地图默认为浏览器ip所定位的城市中心点
				polygon: [ //设置默认选中区域，没有则为[]
					[
						[114.127796, 22.559439],
						[114.131272, 22.559558],
						[114.130671, 22.556546],
						[114.127903, 22.556546],
						[114.126573, 22.557953]
					]
				]
			}
		 */
		value: {
			type: Object
		},
		/**
		 * 默认的地图选址方式，move 移动地图选点 click ：点击地图
		 */
		type: {
			type: String,
			default: 'move',
			volidator: function (val) {
				return ['move', 'click'].includes(val)
			}
		}
	},

	data() {
		return {
			address: '',
			map: null,
			poiList: [],
			amap: null,
			polyEditor: null,
			polygons: {},
			deletePolygons: {},
			instansePolygons: {}
		}
	},
	async mounted() {
		const AMap = await AMapLoader.load({
			key: this.zjyOptions.amapKey, // 申请好的Web端开发者Key，首次调用 load 时必填
			version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
			plugins: ['AMap.Scale', 'AMap.Geocoder', 'AMap.AutoComplete', 'AMap.Geolocation', 'AMap.PolygonEditor'], // 需要使用的的插件列表，如比例尺'AMap.Scale'等
			AMapUI:
				this.type === 'click'
					? {
							version: '1.1',
							plugins: ['overlay/SvgMarker']
					  }
					: null
		})
		this.amap = AMap
	},
	watch: {
		value(val) {
			if (val) {
				if (this.map && this.marker) {
					this.polygons = {}
					if (val.lnglat && Array.isArray(val.lnglat) && val.lnglat.length === 2) {
						this.map.setCenter(val.lnglat)
						this.center = val.lnglat
						this.marker.setPosition(val.lnglat)
						this.geocoder.getAddress(val.lnglat)
						this.address = ''
					}
					if (val.polygon && Array.isArray(val.polygon) && val.polygon.length) {
						const polygonList = val.polygon.map(item => {
							const uuid = getRandomStr()
							const polygonInstance = new this.amap.Polygon({
								path: item,
								extData: {
									id: uuid
								}
							})
							this.polygons[uuid] = polygonInstance.getPath()
							this.instansePolygons[uuid] = polygonInstance
							polygonInstance.on('dblclick', e => {
								this.polyEditor.setTarget(e.target)
								this.polyEditor.open()
							})
							return polygonInstance
						})
						console.log('polygonList', polygonList)
						this.polyEditor.addAdsorbPolygons(polygonList)
					}
				}
			}
		},
		amap(val) {
			// watch地图的amap是因为amap的加载是个异步的过程
			if (val) {
				this.getLocaltion()
				// 如果amap初始化好了以后弹框打开了，则实例化地图
				if (this.$attrs.visible) {
					this.initMap()
				}
			}
		}
	},
	methods: {
		getLocaltion() {
			// 定位当前位置
			this.geolocation = new this.amap.Geolocation({
				// 是否使用高精度定位，默认：true
				enableHighAccuracy: true,
				// 设置定位超时时间，默认：无穷大
				timeout: 10000,
				// 定位按钮的停靠位置的偏移量，默认：Pixel(10, 20)
				buttonOffset: new this.amap.Pixel(10, 20),
				//  定位成功后调整地图视野范围使定位位置及精度范围视野内可见，默认：false
				zoomToAccuracy: true,
				//  定位按钮的排放位置,  RB表示右下
				buttonPosition: 'RB'
			})
			this.geolocation.getCurrentPosition((status, result) => {
				if (status === 'complete') {
					this.center = result.position
					console.log('定位成功', result)
					if (this.map) {
						this.geocoder.getAddress(result.position)
						this.address = ''
						if (this.type === 'click') {
							this.marker.setPosition(result.position)
						}
					}
				}
			})
		},
		opened() {
			if (this.amap) {
				this.initMap()
			}
		},
		close() {
			this.$emit('update:visible', false)
		},
		initMap() {
			if (this.map) return
			let center = this.center || null
			let initPolygon = []
			const isObject = Object.prototype.toString.call(this.value) === '[object Object]'
			if (isObject) {
				const { lnglat, polygon } = this.value
				if (lnglat) {
					const type = Object.prototype.toString.call(lnglat)
					if (type === '[object Array]') {
						if (lnglat.length) {
							center = new this.amap.LngLat(...lnglat)
						}
					} else if (type === '[object Object]') {
						center = lnglat
					}
				}
				if (polygon && Array.isArray(polygon)) {
					initPolygon = polygon.map((item, index) => {
						console.log(item)
						const uuid = getRandomStr()
						const polygonInstance = new this.amap.Polygon({
							path: item,
							extData: {
								id: uuid
							}
						})
						this.polygons[uuid] = item
						this.instansePolygons[uuid] = polygonInstance

						polygonInstance.on('dblclick', e => {
							this.polyEditor.setTarget(e.target)
							this.polyEditor.open()
						})
						return polygonInstance
					})
				}
			}
			this.map = new this.amap.Map('map-container', {
				zoom: 16,
				center
			})
			console.log('initPolygon', initPolygon)
			this.map.add(initPolygon)
			this.map.setFitView()
			// 多边形编辑与绘制
			this.polyEditor = new this.amap.PolygonEditor(this.map, initPolygon, {
				createOptions: {
					fillColor: '#00b0ff',
					strokeColor: '#80d8ff'
				}
			})
			this.polyEditor.addAdsorbPolygons(initPolygon)
			if (initPolygon.length) {
				const last = initPolygon[initPolygon.length - 1]
				this.polyEditor.setTarget(last)
				this.polyEditor.open()
			}
			this.polyEditor.on('add', data => {
				var polygon = data.target
				const uuid = getRandomStr()
				polygon.setExtData({
					id: uuid
				})
				this.polygons[uuid] = polygon.getPath()
				this.instansePolygons[uuid] = polygon

				console.log('添加的id', uuid)
				console.log('添加的polygons', this.polygons)

				this.polyEditor.addAdsorbPolygons(polygon)
				polygon.on('dblclick', () => {
					this.polyEditor.setTarget(polygon)
					this.polyEditor.open()
				})
			})
			// .on('adjust', e => {
			// 	const { id } = e.target.getExtData()
			// 	console.log('adjust', id)
			// 	this.polygons[id] = e.target.getPath()
			// 	console.log('adjust', this.polygons)
			// })
			this.polyEditor.on('end', e => {
				if (!Array.isArray(e.target)) {
					const { id } = e.target.getExtData()
					if (!this.deletePolygons[id]) {
						console.log('end', id)
						this.polygons[id] = e.target.getPath()
					}
				}
			})
			var scale = new this.amap.Scale()
			// 添加距离标尺
			this.map.addControl(scale)
			// 添加定位点
			// this.map.addControl(this.geolocation)

			this.autoComplete = this.autoComplete || new this.amap.AutoComplete()

			this.geocoder =
				this.geocoder ||
				new this.amap.Geocoder({
					radius: 1000, // 以中心为范围1000米
					extensions: 'all' // 返回所有信息
				})
			this.geocoder.on('complete', this.geocoder_CallBack)
			const fn = {
				move: () => {
					this.map.on('dragend', this.mapMoveend)
					this.mapMoveend()
				},
				click: () => {
					// eslint-disable-next-line
					var shape = new AMapUI.SvgMarker.Shape.WaterDrop({
						// 图标主题
						height: 30,
						fillColor: colorTheme, // 填充色
						offset: [-15, -30],
						strokeColor: null,
						strokeWidth: 0
					})
					// eslint-disable-next-line
					this.marker = new AMapUI.SvgMarker(
						// 第一个参数传入shape实例
						shape,
						// 第二个参数为SimpleMarker的构造参数（iconStyle除外）
						{
							map: this.map,
							position: this.map.getCenter()
						}
					)
					this.mapClick({
						lnglat: this.map.getCenter()
					})
					this.map.on('click', this.mapClick)
				}
			}
			fn[this.type]()
		},
		mapUnfoucs() {
			this.polyEditor && this.polyEditor.close()
		},
		createPolygon() {
			console.log('点击添加时的polygons', this.polygons)

			this.$message({
				message: '请点击地图进行绘制',
				type: 'info'
			})
			// this.polyEditor.close()
			this.polyEditor.setTarget()
			this.polyEditor.open()
		},
		deletePolygon() {
			const current = this.polyEditor.getTarget()
			// current有三种返回状态
			console.log('current', current)
			// 1、初始化时没有通过addAdsorbPolygons添加区域时，则getTarget()会返回一个[]
			// 2、返回最后一个编辑的对象
			// 3、返回undefined
			if (Array.isArray(current)) {
				return this.$message({
					message: '没有可删除的区域，请先添加区域',
					type: 'error'
				})
			}

			if (current) {
				const { id } = current.getExtData()
				console.log('id', id)
				console.log('polygons', Object.keys(this.polygons))
				if (this.polygons[id]) {
					this.polyEditor.close()
					this.map.remove(current)
					this.$delete(this.polygons, id)
					this.deletePolygons[id] = true

					const keys = Object.keys(this.polygons)
					console.log('keys', keys)
					if (keys.length) {
						const lastInstance = this.instansePolygons[keys[keys.length - 1]]
						this.polyEditor.setTarget(lastInstance)
					} else {
						this.polyEditor.setTarget()
					}
					this.$delete(this.instansePolygons, id)

					console.log('删除的id', id)
					console.log('删除后剩余', Object.keys(this.polygons))
					console.log('删除后deletePolygons', this.deletePolygons)
					console.log('删除后instansePolygons', this.instansePolygons)
				} else {
					return this.$message({
						message: '请先添加区域',
						type: 'error'
					})
				}
			} else {
				return this.$message({
					message: '没有可删除的区域，请先添加区域',
					type: 'error'
				})
			}
		},
		finash() {
			this.polyEditor && this.polyEditor.close()
		},
		mapClick(e) {
			this.map.setCenter(e.lnglat)
			this.center = e.lnglat
			this.marker.setPosition(e.lnglat)
			this.geocoder.getAddress(e.lnglat)
			this.address = ''
		},
		mapMoveend() {
			const center = this.map.getCenter()
			this.center = center
			this.geocoder.getAddress(center)
			this.address = ''
		},
		geocoder_CallBack({ regeocode }) {
			console.log('regeocode', regeocode)
			const now = { id: 999, name: '当前选中点', location: this.center, distance: 0, address: regeocode.formattedAddress }
			this.poiList = [now, ...regeocode.pois]
			this.poiList.sort((a, b) => {
				return a.distance - b.distance
			})
			this.$refs['left-warp-bottom'].scrollTo(0, 0)
			this.active = now
		},
		poiClick(item) {
			this.active = { ...item }
			this.map.panTo(item.location)
			this.center = item.location
			this.poiList = this.poiList.filter(data => data.id !== 999)
			if (this.type === 'click') {
				this.marker.setPosition(item.location)
			}
		},
		handleSelect(val) {
			console.log(val)
			this.map.panTo(val.location)
			this.mapMoveend()
		},
		querySearchAsync(queryString, cb) {
			if (!this.autoComplete) return
			this.autoComplete.search(queryString, function (status, result) {
				console.log(status, result)
				if (status === 'complete') {
					const data = result.tips.map(item => ({
						value: item.name,
						...item
					}))
					cb(data)
				} else {
					// eslint-disable-next-line node/no-callback-literal
					cb([])
				}
			})
		},
		confirm() {
			this.polyEditor && this.polyEditor.close()
			this.$nextTick(() => {
				console.log('polygon', this.polygons)

				const polygon = Object.values(this.polygons)

				if (!polygon.length) {
					return this.$message({
						message: '请至少添加一个项目区域',
						type: 'error'
					})
				}
				console.log('polygon', polygon)
				/**
				 * @description v-model
				 * @event input
				 * @type {Event}
				 */
				this.$emit('input', {
					lnglat: this.active.location.toArray(),
					polygon
				})
				/**
				 * @description 点击确定按钮事件
				 * @event click
				 * @type {Event}
				 */
				console.log(this.active)
				this.$emit('confirm', {
					address: this.active.address,
					location: this.active.location,
					lnglat: this.active.location.toArray(),
					polygon
				})

				/**
				 * @description 切换visible状态
				 * @event update:visible
				 * @type {Event}
				 */
				this.$emit('update:visible', false)
			})
		}
	},
	beforeDestroy() {
		if (this.map) {
			this.polygons = {}
			this.map.clearMap()
			this.map.destroy()
			this.map = null
			this.marker = null
			this.autoComplete = null
			this.geocoder.off('complete')
			this.geocode = null
			console.log('closed', this.map)
		}
	}
}
</script>
<style lang="scss" scoped>
.map-warp {
	height: 500px;
	display: flex;
	.left-warp {
		width: 200px;
		margin-right: $margin;
		display: flex;
		flex-direction: column;
		.left-warp-top {
		}
		.left-warp-bottom {
			flex: 1;
			border: 1px solid $color-border-theme;
			margin-top: $margin;
			overflow: hidden;
			overflow-y: auto;
			ul {
				padding: 0 10px;
				.poi-item {
					padding: 5px 0;
					border-bottom: 1px solid $color-border-theme;
					cursor: pointer;
					display: flex;
					.poi-icon {
						width: 20px;
					}
					.poi-content {
						flex: 1;
						.poi-name {
							margin-bottom: 5px;
							font-size: 14px;
						}
						.poi-address {
							font-size: 12px;
							color: $color-text-secondary;
						}
					}
				}
				.active {
					.poi-icon {
						.marker-icon {
							color: $color-theme-regular;
						}
					}
					.poi-content {
						.poi-name {
							color: $color-theme-regular;
						}
						.poi-address {
							color: $color-theme-regular;
						}
					}
				}
			}
		}
	}
	.right-warp {
		flex: 1;
		position: relative;
		.marker-icon {
			position: absolute;
			top: 50%;
			left: 50%;
			transform: translate(-50%, -100%);
			z-index: 1;
			width: 30px;
			height: 30px;
			color: $color-theme;
		}
		#map-container {
			height: 100%;
		}
		.map-tip {
			position: absolute;
			top: 10px;
			left: 10px;
			right: 10px;
		}
		.map-control {
			position: absolute;
			right: 20px;
			bottom: 10px;
			li {
				cursor: pointer;
				background-color: #fff;
				padding: 5px 10px;
				font-size: 14px;
				@include box-shabow;
			}
			li + li {
				margin-top: 10px;
			}
		}
	}
}
</style>
<style lang="scss">
.poi-autocomplete {
	.poi-content {
		line-height: 20px;
		padding: 5px 0;
		.poi-name {
			font-size: 14px;
		}
		.poi-address {
			font-size: 12px;
			color: $color-text-secondary;
		}
	}
}
</style>
